var ImgUpload = function () {
  var template = /* html */ `
    <div class="img-upload clearfix" v-loading.fullscreen.lock="hasLoading&&uploading&&hasFullLoading">
      <el-upload ref="imgUpload" class="img-upload-input" :class="{'can-upload':!readonly&&!uploading}" :accept="accept" :show-file-list="false" :multiple="false" :data="requestData"
        :auto-upload="false" :disabled="readonly||uploading" :drag="drag" action="" :on-change="handleUploadChange" >
        <i v-if="imgUrl===''" class="el-icon-plus img-uploader-icon" :style="uploadIconSize"></i>
        <div v-else class="img-upload-content clearfix" :style="imageSize">
          <el-image :src="formatImgUrl(imgUrl)" fit="scale-down"></el-image>
          <div v-if="imgHandle&&imgHandle.length>0" class="fixed-div upload-img-handle">
            <div class="upload-mask"></div>
            <div class="upload-img-btns">
              <span v-if="imgHandle.indexOf('preview')!==-1" title="预览" @click.stop="previewImg">
                <i class="el-icon-zoom-in"></i>
              </span>
              <span v-if="!readonly&&imgHandle.indexOf('delete')!==-1" title="删除" @click.stop="deleteImg">
                <i class="el-icon-delete"></i>
              </span>
            </div>
          </div>
        </div>
        <div v-if="uploading" class="fixed-div uploader-progress">
          <div class="upload-mask"></div>
          <div class="uploader-progress-content">
            <el-progress type="circle" :percentage="progressValue"></el-progress>
          </div>
        </div>
      </el-upload>
    </div>
  `;

  return {
    props: {
      value: {
        type: String,
        required: true
      },
      imgWidth: {
        type: [String, Number],
        default: 250
      },
      imgHeight: {
        type: [String, Number],
        default: 250
      },
      readonly: {
        type: Boolean,
        default: false
      },
      requestData: Object,
      autoUpload: {
        type: Boolean,
        default: true
      },
      accept: {
        type: String,
        default: 'image/*'
      },
      drag: {
        type: Boolean,
        default: false
      },
      uploadCheckMethod: Function,
      errorMsg: {
        type: String,
        default: '请选择图片格式文件上传'
      },
      imgHandle: {
        type: Array,
        default: function () {
          return ['preview', 'delete'];
        }
      },
      hasWaterMask: {
        type: Boolean,
        default: false
      },
      hasFullLoading: {
        type: Boolean,
        default: false
      },
      hasLoading: {
        type: Boolean,
        default: true
      }
    },

    watch: {
      value: function () {
        if (this.inputValue !== null) {
          this.inputValue = null;
          return;
        }

        this.imgUrl = this.value;
      }
    },

    computed: {
      imageSize: function () {
        var imgWidth = this.imgWidth;
        if (typeof imgWidth === 'number') {
          imgWidth = imgWidth + 'px';
        }
        var imgHeight = this.imgHeight;
        if (typeof imgHeight === 'number') {
          imgHeight = imgHeight + 'px';
        }
        return {
          width: imgWidth,
          height: imgHeight
        }
      },
      uploadIconSize: function () {
        var size = this.imageSize;
        size = _.cloneDeep(size);
        size.lineHeight = size.height;
        return size;
      }
    },

    data: function () {
      return {
        uploading: false,
        imgUrl: this.value,
        inputValue: null,
        progressValue: 0,
        uploadField: null
      };
    },

    methods: {
      handleUploadChange: function (file) {
        var status = file.status;
        if (status !== 'ready') {
          return;
        }

        var self = this;
        this.checkUploadImgValid(file).then(function (flag) {
          if (!flag) {
            return;
          }

          if (self.autoUpload) {
            self.uploadImg(file);
            return;
          }
          var imgUrl = self.imgUrl;
          self.imgUrl = URL.createObjectURL(file.raw);
          self.uploadField = file;
          var type = imgUrl === '' ? 'add' : 'update';
          self.$emit('change', file, type);
        });
      },

      uploadImg: function (file) {
        this.progressValue = 0;
        this.uploading = true;

        var self = this;
        return postImgFileToQiniu('fileManager/getQiniuToken', file.raw, function (percent) {
          self.progressValue = _.round(percent, 2);
        }, this.hasWaterMask,true).then(function (url) {
          self.uploading = false;
          if (self.autoUpload) {
            self.imgUrl = URL.createObjectURL(file.raw);
          } else {
            self.uploadField = null;
          }
          self.$refs.imgUpload.clearFiles();
          self.inputValue = url;
          self.$emit('input', url);
          self.$emit('upload-success', url);
          return url;
        }).catch(function (error) {
          self.uploading = false;
          self.$refs.imgUpload.clearFiles();
          self.$alert('图片上传失败');
          self.$emit('upload-error', error);
          throw error;
        });
      },

      checkUploadImgValid: function (file) {
        var uploadCheckMethod = this.uploadCheckMethod;
        if (uploadCheckMethod !== undefined) {
          if (typeof uploadCheckMethod !== 'function') {
            throw new Error('uploadCheckMethod is not a function');
          }
          return uploadCheckMethod(file.raw);
        }

        var type = file.raw.type;
        var valid = type.indexOf('image/') === 0;
        if (!valid) {
          this.$message.error({
            message: this.errorMsg,
            duration: 2000
          });
        }
        return Promise.resolve(valid);
      },

      previewImg: function () {
        var imgUrl = this.imgUrl;
        this.$msgbox({
          title: ' ',
          message: `<img style="display:block;margin:auto" src="${imgUrl}">`,
          customClass: 'preview-message-box',
          dangerouslyUseHTMLString: true,
          showClose: true,
          showConfirmButton: false,
          showCancelButton: false,
          callback: function () {}
        });
      },

      deleteImg: function () {
        var imgUrl = this.imgUrl;
        this.imgUrl = '';
        this.uploadField = null;
        this.inputValue = '';
        this.$emit('input', '');
        this.$emit('delete', imgUrl);
      },

      submit: function () {
        var uploadField = this.uploadField;
        if (uploadField === null) {
          this.$emit('upload-success', this.value);
          return Promise.resolve(this.value);
        }
        return this.uploadImg(uploadField);
      },

      checkImgExist: function () {
        return this.imgUrl !== '';
      }
    },

    template: template
  };
}();

var ImgsUpload = function () {
  var template = /* html */ `
    <div class="imgs-upload" v-loading.fullscreen.lock="loading">
      <template v-for="(imgUrl,index) in imgUrls">
        <img-upload v-if="!readonly||(readonly&&imgUrl.url!=='')" ref="imgUpload" :key="imgUrl.id" v-model="imgUrl.url" :auto-upload="autoUpload" :drag="drag"
          :upload-check-method="uploadCheckMethod" :error-msg="errorMsg" :img-handle="imgHandle" :has-water-mask="hasWaterMask" :readonly="readonly||readonlyImg.indexOf(imgUrl.url)!==-1"
          :has-full-loading="!autoUpload" :img-width="imgWidth" :img-height="imgHeight" @delete="deleteImg(index)" @change="uploadChange" @upload-success="uploadSuccess">
        </img-upload>
      </template>
    </div>
  `;

  return {
    props: {
      value: {
        type: Array,
        required: true
      },
      imgWidth: [String, Number],
      imgHeight: [String, Number],
      readonly: {
        type: Boolean,
        default: false
      },
      readonlyImg: {
        type: Array,
        default: function () {
          return [];
        }
      },
      autoUpload: {
        type: Boolean,
        default: true
      },
      drag: {
        type: Boolean,
        default: false
      },
      uploadCheckMethod: Function,
      errorMsg: {
        type: String,
        default: '请选择图片格式文件上传'
      },
      imgHandle: {
        type: Array,
        default: function () {
          return ['preview', 'delete'];
        }
      },
      hasWaterMask: {
        type: Boolean,
        default: false
      },
      limit: {
        type: Number,
        default: 0
      }
    },

    data: function () {
      return {
        loading: false,
        inputValue: null,
        imgUrls: this.getImgUrls()
      };
    },

    watch: {
      value: function () {
        if (this.inputValue !== null) {
          this.inputValue = null;
          return;
        }
        this.imgUrls = this.getImgUrls();
      }
    },

    methods: {
      getImgUrls: function () {
        var value = this.value;
        var imgUrls = _.cloneDeep(value);
        imgUrls = _.map(imgUrls, function (imgUrl) {
          return {
            id: SysUtil.getId(),
            url: imgUrl
          };
        });

        var limit = this.limit;
        if (limit === 0 || imgUrls.length < limit) {
          imgUrls.push({
            id: SysUtil.getId(),
            url: ''
          });
        }
        return imgUrls;
      },

      deleteImg: function (index) {
        this.imgUrls.splice(index, 1);
        this.imgsChange();
      },

      addImg: function () {
        var imgUrls = this.imgUrls;
        var limit = this.limit;
        if (limit === 0 || imgUrls.length < limit) {
          imgUrls.push({
            id: SysUtil.getId(),
            url: ''
          });
        }
      },

      uploadChange: function (file, type) {
        if (!this.autoUpload) {
          if (type === 'add') {
            this.addImg();
          }
        }
      },

      uploadSuccess: function () {
        if (this.autoUpload) {
          this.addImg();
          this.imgsChange();
          return;
        }
      },

      imgsChange: function () {
        var imgUrls = this.imgUrls;
        var urls = [];
        for (var i = 0; i < imgUrls.length; i++) {
          var imgUrl = imgUrls[i];
          var url = imgUrl.url;
          if (url !== '') {
            urls.push(url);
          }
        }

        this.inputValue = urls;
        this.$emit('input', urls);
        this.$emit('change', urls);
      },

      submit: function () {
        var imgUploads = this.$refs['imgUpload'];
        var promiseList = [];
        for (var i = 0; i < imgUploads.length; i++) {
          var imgUpload = imgUploads[i];
          promiseList.push(imgUpload.submit());
        }

        this.loading = true;
        var self = this;
        return Promise.all(promiseList).then(function (res) {
          self.imgsChange();
          self.loading = false;
          return res;
        }).catch(function (error) {
          self.loading = false;
          throw error;
        });
      }
    },

    components: {
      ImgUpload: ImgUpload
    },

    template: template
  };
}();
